package channelService

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelStatus"
	"gitee.com/fierce_wolf/go-fox-edge-common/commConfig"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/ChanSyncObj"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"go-fox-edge-channel-tcp-client/channelEntity"
	"strconv"
	"sync"
)

type channelService struct {
	channelName2Entity sync.Map
}

func (e *channelService) getChannelNames() map[string]interface{} {
	result := make(map[string]interface{})
	service.channelName2Entity.Range(func(key, ctx interface{}) bool {
		result[key.(string)] = ctx
		return true
	})

	return result
}

func (e *channelService) OpenChannel(channelName string, channelParam map[string]interface{}) error {
	host := Map.GetString(channelParam, "host", "")
	port := Map.GetInt(channelParam, "port", 0)

	channelStatus.UpdateParamStatus(channelName, "connected", false)

	// 检查：参数是否为空
	if Method.HasEmpty(host) || !Map.Has(channelParam, "port") {
		return errors.New("参数不能为空: host, port ")
	}

	// 获得全局配置的接收缓存大小
	recvBuffSize := 4096
	configValue, _ := commConfig.GetConfigParam("serverConfig")
	if configValue != nil {
		recvBuffSize = Map.GetInt(configValue, "recvBuffSize", 4094)
		if recvBuffSize < 256 {
			recvBuffSize = 256
		}
	}

	entity := &channelEntity.TcpClientEntity{}
	entity.RemoteHost = host
	entity.RemotePort = port
	entity.SocketAddress = host + ":" + strconv.Itoa(port)
	entity.ChannelName = channelName
	entity.RecvBuffSize = recvBuffSize

	e.channelName2Entity.Store(channelName, entity)

	// 为通道创建一个多线程消息交换的chan
	ChanSyncObj.Instance(channelName)
	return nil
}

func (e *channelService) CloseChannel(channelName string, channelParam map[string]interface{}) error {
	// 关闭socket
	ctx := channelManager.getContextByServiceKey(channelName)
	if ctx != nil {
		ctx.Close()
	}

	// 删除记录
	e.channelName2Entity.Delete(channelName)

	// 释放掉为该通道创建的多线程之间消息交换的chan
	ChanSyncObj.Release(channelName)
	return nil
}

func (e *channelService) Execute(requestVO *commRedisRpc.ChannelRequestVO) (*commRedisRpc.ChannelRespondVO, error) {
	val, ok := e.channelName2Entity.Load(requestVO.Name)
	if !ok {
		return nil, errors.New("通道的配置参数不正确，未能注册通道成功:" + requestVO.Name)
	}
	entity := val.(*channelEntity.TcpClientEntity)

	ctx := channelManager.getContextByServiceKey(entity.ChannelName)
	if ctx == nil {
		return nil, errors.New("与远端尚未建立连接:" + requestVO.Name)
	}

	return execute.execute(ctx, requestVO)
}
